#include <cstdio>
#include <memory>
#include "vl_tunnel.h"

using namespace VL;

class TransportTunnel : public BaseTunnel {
public:
	TransportTunnel(int number): number(number) {

	}

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-14 17:25:09
	 * 
	 * 传递数据方法
	 * @param data 管道数据
	 * 
	 * @note 通过参数中的数据块获取数据进行处理, 可以选择继续向下传递或者抛出异常交由上/下线 Tunnel 处理
	 */
	virtual void doPass(const std::shared_ptr<TunnelData>& data) {
		printf("doPass - %d\n", this->number);
		BaseTunnel::doPass(data);
	}

	/**
	 * @Author: CimZzz
	 * @Date: 2022-07-14 17:25:14
	 * 
	 * 回复数据方法
	 * @param data 管道数据
	 * 
	 * @note 通过参数中的数据块获取数据进行处理, 可以选择继续向上回复或者抛出异常交由上/下线 Tunnel 处理
	 */
	virtual void doReply(const std::shared_ptr<TunnelData>& data) {
		printf("doReply - %d\n", this->number);
		BaseTunnel::doReply(data);
	}

private:
	int number;
};

int main() {
	Terminator inTerm;
	Terminator outTerm;
	inTerm.setupDataCallback([](const std::shared_ptr<TunnelData>& data){
		printf("input term recv reply: %d\n", *data->memoryCast<int>());
	});
	outTerm.setupDataCallback([&outTerm](const std::shared_ptr<TunnelData>& data){
		int number = *data->memoryCast<int>();
		printf("output term recv pass: %d, will reply: %d\n", number, number * 10);
		outTerm.passData(TunnelData::newData<int>(new int(number * 10)));
	});

	inTerm.input(new TransportTunnel(1))->connect(new TransportTunnel(2))->connect(new TransportTunnel(3))->connect(new TransportTunnel(4))->output(&outTerm);
	inTerm.passData(TunnelData::newData<int>(new int(1)));
	inTerm.passData(TunnelData::newData<int>(new int(2)));
	inTerm.passData(TunnelData::newData<int>(new int(3)));
	inTerm.passData(TunnelData::newData<int>(new int(4)));
	inTerm.passData(TunnelData::newData<int>(new int(5)));
	inTerm.destroyAll();
	inTerm.passData(TunnelData::newData<int>(new int(1)));
	outTerm.destroyAll();
	inTerm.passData(TunnelData::newData<int>(new int(1)));
	return 0;
}